'''
    Goblinoid: Experience all of MediaGoblin on an Android Device
    Copyright (C) 2015 Dylan Jeffers

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
'''

# models for app root
from __future__ import print_function
from os.path import join

from kivy.app import App
from kivy.properties import ObjectProperty, DictProperty, ListProperty
from kivy.uix.widget import Widget

from pypump.models.note import Note as PumpNote
from pypump.models.image import Image as PumpImage
from pypump import JSONStore
from pypump.exception import PyPumpException
import requests


# store for user's credentials
class UserStore(JSONStore):
    @classmethod
    def get_filename(cls):
        return join(App.get_running_app().user_data_dir,
                    'MediaGoblin/credentials.json')


class PumpModel(Widget):
    feed_content = ObjectProperty(None)
    pump = ObjectProperty(None)
    screen_dict = DictProperty()
    inbox = ListProperty()
    feed_data = ListProperty()

    def __init__(self, **kwargs):
        super(PumpModel, self).__init__(**kwargs)
        self.init_screen_dict()
        self.data_dir = join(App.get_running_app().user_data_dir,
                             'MediaGoblin')
        self.init_screen_dict()

    def get_data_dir(self):
        return self.data_dir

    def init_screen_dict(self):
        import loginview
        import actionview
        import screenviews
        self.screen_dict = dict([
            ('login', loginview.Login),
            ('webfinger', loginview.WebFinger),
            ('verify', loginview.Verify),
            ('enter', loginview.EnterApp),
            ('action', actionview.ActionLayout),
            ('settings', actionview.SettingsScreen),
            ('feed', screenviews.FeedView), ('media', screenviews.MediaView),
            ('profile', screenviews.ProfileView)
            ])

    def on_screen_dict(self, instance, value):
        print ('updated screen dict')

# TODO function much too complicated, clean up
    def on_pump(self, instance, pump):
        print ('on_pump commencing')
        inbox = []
        data = []
        index = 0
# TODO may want to skip bad data rather than breaking out from for loop
        try:
            for activity in pump.me.inbox.major[:5]:
                inbox.append(activity)
                data_dict = self.build_data_dict(activity, index)
                data.append(data_dict)
                data_dict = {}
                index += 1
            self.inbox = inbox
            self.feed_data = data
        except KeyError, e:
            print('KeyError: {0}'.format(e))
            self.inbox = inbox
            self.feed_data = data

    def build_data_dict(self, activity, index):
        data_dict = dict([
            ('index', index),
            ('actor', str(activity.obj.author)),
            ('post_time', [str(activity.published.hour),
                           str(activity.published.minute)]),
            ('likes', self.display_likes(activity)),
            ('comments', self.display_comments(activity)),
            ('description', ''),
            ('image_content', ''),
            ('note_content', ''),
            ('else_content', '')
            ])
        print (len(data_dict['comments']))
        print(data_dict)
        data_dict.update(self.parse_activity_types(activity, index))
        return data_dict

    def parse_activity_types(self, activity, photo_index):
        if isinstance(activity.obj, PumpImage):
            return self.is_image_activity(activity, photo_index)
        elif isinstance(activity.obj, PumpNote):
            try:
                note_text = activity.obj.content
                return {"note_content": note_text}
            except AttributeError, e:
                note_text = e
                return {'note_content': note_text}
            except Exception, e1:
                note_text = e1
                return {'note_content': note_text}
        else:
            else_text = 'cannot display media'
            return {("else_content", else_text),
                    ("description", 'no description')}

    def is_image_activity(self, activity, photo_index):
        try:
            url = activity.obj.original.url
            image_dir = './downloaded_images/image{0}.png'.format(photo_index)
            fout = open(image_dir, 'wb')
            client = self.pump.setup_oauth_client()
            request = requests.get(url, auth=client)
            fout.write(request.content)
            print('got request')
            description = activity.obj.content
            if description is None:
                description = 'no description'
            return {("image_content", image_dir),
                    ("description", description)}
        except AttributeError, e:
            return {("else_content", e),
                    ("description", 'no description')}
        except Exception, e1:
            return {("else_content", e1),
                    ("description", 'no description')}

    def is_note_activity(self, activity):
        pass

    def is_video_activity(self, activity):
        pass

    def display_likes(self, activity):
        try:
            total_likes = activity.obj.likes.total_items
            if total_likes > 0:
                return '{0} likes'.format(str(total_likes))
            else:
                return 'no likes yet'
        except AttributeError:
            return 'no likes yet'
        except KeyError:
            return 'mediagoblin doesn\'t support likes yet'

    def display_description(self, activity):
        try:
            return str(activity.obj.description)
        except AttributeError:
            return 'no description'


# TODO function is much too complicated, clean up
    def display_comments(self, activity):
        comment_array = []

        def build_comment_dict(author, content):
            return dict([
                        ("author", author),
                        ("content", content)
                        ])

        def comment_array_len(comment_array):
            pass
            # print ('len: {0}'.format(len(comment_array)))

        try:
            activity.obj.comments
            for comment in activity.obj.comments:
                try:
                    author = str(comment.author)
                    content = str(comment.content)
                except UnicodeEncodeError, e1:
                    print('display_comments: {0}'.format(e1))
                    author = 'Unicode Error'
                    content = str(e1)
                except PyPumpException, e2:
                    print('display_comments: {0}'.format(e2))
                    author = 'PyPumpException'
                    content = str(e2)
                comment_array.append(build_comment_dict(author, content))
            if len(comment_array) == 0:
                comment_array.append(build_comment_dict('', 'no comments yet'))
            comment_array_len(comment_array)
            return comment_array
        except AttributeError, e:
            print('display_comments: {0}'.format(e))
            comment_array.append(build_comment_dict('AttributeError', str(e)))
            comment_array_len(comment_array)
            return comment_array
        except Exception, e1:
            print('display_comments: {0}'.format(e1))
            comment_array.append(build_comment_dict('ExceptionError', str(e1)))
            comment_array_len(comment_array)
            return comment_array
